<template>
  <VxeBasicTable
    ref="tableRef"
    v-bind="getBindValues"
    :loading="loadingRef"
    @sort-change="onTableChange"
    @page-change="onTableChange"
    @cell-click="cellClickEvent"
    @cell-dblclick="cellDblclickEvent"
    @cell-menu="cellMenuEvent"
    @cell-mouseenter="cellMouseenterEvent"
    @cell-mouseleave="cellMouseleaveEvent"
    @edit-closed="editClosedEvent"
    @edit-activated="editActivatedEvent"
    @edit-disabled="editDisabledEvent"
    @scroll="scrollEvent"
    @radio-change="radioChangeEvent"
    @checkbox-change="checkboxChangeEvent"
    @checkbox-all="checkboxChangeEvent"
    @checkbox-range-change="checkboxChangeEvent"
  >
    <template #form v-if="!$slots.form && (getBindValues.searchForm || getBindValues.customForm)">
      <template v-if="getBindValues.searchForm">
        <SearchForm
          ref="formRef"
          v-bind="getSearchFormProps"
          @register="registerSearchForm"
          @search-click="handleSearchClick"
        />
      </template>
      <template v-else-if="getBindValues.customForm">
        <BasicForm
          ref="formRef"
          submitOnReset
          v-bind="getFormProps"
          :tableAction="tableAction"
          @register="registerForm"
          @submit="handleSearchInfoChange"
        >
          <template #[replaceFormSlotKey(item)]="data" v-for="item in getFormSlotKeys">
            <slot :name="item" v-bind="data || {}"></slot>
          </template>
        </BasicForm>
      </template>
    </template>

    <template #toolbar_buttons v-if="!$slots.toolbar_buttons">
      <TableTitle
        :title="getBindValues.tbTitle"
        :help-message="getBindValues.tbHelpMessage"
        :get-table-fn="() => tableRef"
      />
      <slot name="title"></slot>
    </template>
    <template #toolbar_tools v-if="!$slots.toolbar_tools">
      <slot name="tools"></slot>
    </template>

    <template #expandContent="data" v-if="!$slots.expandContent">
      <div :style="`width:${expandContentWidth};margin-left:${expandContentLeft}px`">
        <slot name="expandedRowRender" v-bind="data || {}"></slot>
      </div>
    </template>

    <!-- <template #bodyCell="data">
      <slot name="bodyCell" v-bind="data || {}"></slot>
    </template> -->

    <template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
      <slot :name="item" v-bind="data || {}"></slot>
    </template>
  </VxeBasicTable>

  <DetailFormModal @register="registerDetailModal" v-bind="getDetailFormProps" />
</template>
<script lang="ts" setup>
  import { ref, computed, unref, toRaw, useAttrs, onMounted, onUnmounted } from 'vue';
  import {
    VxeBasicTable,
    VxeGridInstance,
    VxeTablePropTypes,
    VxeGridDefines,
    // VxeGridEvents,
  } from '@/components/VxeTable';
  import { omit } from 'lodash-es';

  import { useI18n } from '@/hooks/web/useI18n';

  import { BasicForm, useForm } from '@/components/Form/index';

  import { usePagination } from './hooks/usePagination';

  import { isFunction, isBoolean } from '@/utils/is';
  // import { buildShortUUID } from '@/utils/uuid';

  import { useModal } from '@/components/AdVxeModal';
  import { FormModeEnum } from '@/enums/formEnum';

  import { FilterGroup } from '@/utils/common/types';

  import type { TableProps, TableActionType, AdColumn } from './types/table';
  import { adVxeTableProps } from './props';
  import { useDataSource } from './hooks/useDataSource';
  import { useSearchForm } from './hooks/useSearchForm';
  import { useDetailForm } from './hooks/useDetailForm';
  import TableTitle from './components/TableTitle.vue';
  import SearchForm from './components/SearchForm.vue';
  import DetailFormModal from './components/DetailFormModal.vue';

  defineOptions({ name: 'AdVxeTable' });
  const props = defineProps(adVxeTableProps);
  const emit = defineEmits([
    'fetch-success',
    'fetch-error',
    'selection-change',
    'register',
    'cell-click',
    'cell-dbclick',
    'cell-menu',
    'cell-mouseenter',
    'cell-mouseleave',
    'edit-closed',
    'edit-activated',
    'edit-disabled',
    'scroll',
    'expanded-rows-change',
    'change',
    'columns-change',
    'radio-change',
    'checkbox-change',
  ]);
  const attrs = useAttrs();

  const { t } = useI18n();

  const tableRef = ref<VxeGridInstance>();
  const tableDataRef = ref<VxeTablePropTypes.Data>([]);

  const formRef = ref(null);
  const innerPropsRef = ref<Partial<TableProps>>();

  const [registerForm] = useForm();

  // 表格配置项
  const getProps = computed(() => {
    return { ...props, ...unref(innerPropsRef) } as TableProps;
  });

  // 表格对象
  const getTable = computed(() => unref(tableRef));

  // 加载状态
  const loadingRef = ref(false);
  const getLoading = computed(() => loadingRef.value);
  const setLoading = (loading: boolean) => {
    loadingRef.value = loading;
  };

  // 分页
  const { getPaginationInfo, getPagination, setPagination } = usePagination(getProps);

  //搜索表单
  const {
    getSearchFormProps,
    register: registerSearchForm,
    methods: searchFormActions,
  } = useSearchForm(getProps, getLoading);

  //数据源
  const {
    handleChange: onTableChange,
    getDataRef,
    getData,
    getSearchInfo,
    setData,
    fetch,
    reload,
  } = useDataSource(
    getProps,
    getTable,
    {
      getPaginationInfo,
      tableDataRef,
      setPagination,
      setLoading,
      getSearchInfo: searchFormActions.getSearchInfo,
    },
    emit,
  );

  //数据列
  const getColumns = computed(() => {
    let columns: AdColumn[] = [];
    // 序号列
    if (getProps.value?.showSeqColumn) {
      columns.push({
        title: t('component.table.index'),
        type: 'seq',
        fixed: 'left',
        width: '50',
        align: 'center',
        ...getProps.value?.seqColumnProps,
        field: undefined,
      });
    }
    // 选择列
    if (getProps.value?.selection) {
      columns.push({
        type: getProps.value.selection,
        fixed: 'left',
        width: 45,
        align: 'center',
        ...getProps.value?.selectColumnProps,
        field: undefined,
      });
    }
    // 展开行
    if (getProps.value?.expand) {
      columns.push({
        type: 'expand',
        fixed: 'left',
        width: '30',
        align: 'center',
        slots: { content: 'expandContent' },
        ...getProps.value?.expandColumnProps,
        field: undefined,
      });
    }
    // 数据列
    if (getProps.value?.columns) {
      columns = [...columns, ...getProps.value.columns];
    }
    // 操作列
    if (getProps.value?.actionColumn) {
      columns.push({ ...getProps.value?.actionColumn, field: undefined });
    }
    return columns;
  });

  interface TablePropsInner extends TableProps {
    /** 表格标题 */
    tbTitle?: string | ((data: Recordable) => string);
    /** 表格标题右侧提示信息 */
    tbHelpMessage?: string | string[];
  }
  const getBindValues = computed(() => {
    const data = unref(getDataRef);
    let attr: TablePropsInner = {
      ...attrs,
      ...unref(getProps),
      loading: unref(getLoading),
      columns: toRaw(unref(getColumns)),
      pagerConfig: toRaw(unref(getPaginationInfo)),
      data,
      id: unref(getProps).id || undefined,
      headerAlign: unref(getProps).headerAlign || 'center',
      showOverflow: unref(getProps).showOverflow || 'tooltip',
      keepSource: unref(getProps).keepSource || true,
      height: unref(getProps).height || 'auto',
      autoResize: unref(getProps).autoResize || true,
      proxyConfig: {
        enabled: false,
        ajax: {
          // 接收 Promise
          query: () => {
            return reload();
          },
        },
      },
      toolbarConfig: {
        ...unref(getProps).toolbarConfig,
        slots: {
          buttons: unref(getProps).toolbarConfig?.slots?.buttons || 'toolbar_buttons',
          tools: unref(getProps).toolbarConfig?.slots?.tools || 'toolbar_tools',
        },
      },
      rowConfig: {
        ...unref(getProps).rowConfig,
        isCurrent: unref(getProps).rowConfig?.isCurrent || true,
        // resizable: unref(getProps).rowConfig?.resizable || true,
      },
      columnConfig: {
        ...unref(getProps).columnConfig,
        isCurrent: unref(getProps).columnConfig?.isCurrent || false,
        resizable: unref(getProps).columnConfig?.resizable || true,
      },
      sortConfig: {
        ...unref(getProps).sortConfig,
        multiple: unref(getProps).sortConfig?.multiple || true,
        chronological: unref(getProps).sortConfig?.chronological || true,
      },
      tbTitle: unref(getProps).title,
      tbHelpMessage: unref(getProps).helpMessage,
    };
    // 工具栏
    if (attr.toolbarConfig?.refresh) {
      if (isBoolean(attr.toolbarConfig?.refresh)) {
        attr.toolbarConfig.refresh = { queryMethod: () => reload };
      } else {
        attr.toolbarConfig.refresh = { ...attr.toolbarConfig?.refresh, queryMethod: () => reload };
      }
    }
    // 序号列
    if (attr.showSeqColumn && !attr.seqConfig?.seqMethod) {
      const currentPage = getPaginationInfo.value?.currentPage;
      const pageSize = getPaginationInfo.value?.pageSize;
      if (currentPage && pageSize) {
        if (attr.seqColumnRule === 'default') {
          attr.seqConfig = {
            ...attr.seqConfig,
            seqMethod: (params) => {
              return params.rowIndex + 1;
            },
          };
        } else if (attr.seqColumnRule === 'page') {
          attr.seqConfig = {
            ...attr.seqConfig,
            seqMethod: (params) => {
              return (currentPage - 1) * pageSize + (params.rowIndex + 1);
            },
          };
        }
      }
    }
    // 自定义配置-storage
    if (
      (attr.customConfig?.storage === undefined || attr.customConfig?.storage === null) &&
      attr.id
    ) {
      attr.customConfig = {
        ...attr.customConfig,
        storage: true,
      };
    }
    return omit(attr, 'title', 'helpMessage');
  });

  function setProps(props: Partial<TableProps>) {
    innerPropsRef.value = { ...unref(innerPropsRef), ...(props || {}) };
  }

  const tableAction: TableActionType = {
    getTable: () => getTable.value,
    openDetailForm,
    reload,
    setPagination,
    setLoading,
    getData,
    getSearchInfo,
    setData,
    setProps,
    getPagination: getPagination,
    getColumns: () => getColumns.value,
    emit,
  };

  //详情表单
  const { getDetailFormProps } = useDetailForm(getProps, reload);
  const [registerDetailModal, detailModalMethods] = useModal();

  emit('register', tableAction, searchFormActions, detailModalMethods);

  /** 处理搜索按钮点击 */
  async function handleSearchClick(info: FilterGroup) {
    const { searchInfoFn } = unref(getProps);
    if (searchInfoFn && isFunction(searchInfoFn)) {
      info = (await searchInfoFn(info)) || info;
    }
    await fetch({ searchInfo: info, page: 1 });
  }

  /** 打开详情表单 */
  function openDetailForm(formMode: FormModeEnum, record?: Recordable) {
    //TODO:高级详情表单的弹窗
    detailModalMethods.openModal(true, {
      formMode: formMode,
      record: record,
    });
  }

  /** 单元格被点击时会触发该事件 */
  async function cellClickEvent(e: VxeGridDefines.CellClickEventParams) {
    const table = getTable.value;
    if (table && getProps.value?.clickToSelect && getProps.value?.selection) {
      // const rowIndex = e.rowIndex;
      const selection = getProps.value.selection;
      if (selection === 'radio') {
        const radioRow = table.getRadioRecord();
        if (radioRow) {
          if (radioRow === e.row) {
            table.clearRadioRow();
          } else {
            table.clearRadioRow();
            table.setRadioRow(e.row);
          }
        } else {
          table.setRadioRow(e.row);
        }
        emit('radio-change', e);
      } else if (selection === 'checkbox') {
        table.toggleCheckboxRow(e.row);
        emit('checkbox-change', e);
      }
    }
    emit('cell-click', e);
  }
  /** 单元格被双击时会触发该事件 */
  async function cellDblclickEvent(e: VxeGridDefines.CellDblclickEventParams) {
    emit('cell-dbclick', e);
  }
  /** 只对 menu-config 配置时有效，单元格被鼠标右键时触发该事件 */
  async function cellMenuEvent(e: VxeGridDefines.CellMenuEventParams) {
    emit('cell-menu', e);
  }
  /** 只对 tooltip-config 配置时有效，当鼠标移动到单元格时会触发该事件 */
  async function cellMouseenterEvent(e: VxeGridDefines.CellMouseenterEventParams) {
    emit('cell-mouseenter', e);
  }
  /** 只对 tooltip-config 配置时有效，当鼠标移开单元格时会触发该事件 */
  async function cellMouseleaveEvent(e: VxeGridDefines.CellMouseleaveEventParams) {
    emit('cell-mouseleave', e);
  }
  /** 只对 edit-config 配置时有效，单元格编辑状态下被关闭时会触发该事件 */
  async function editClosedEvent(e: VxeGridDefines.EditClosedEventParams) {
    emit('edit-closed', e);
  }
  /** 只对 edit-config 配置时有效，单元格被激活编辑时会触发该事件 */
  async function editActivatedEvent(e: VxeGridDefines.EditActivatedEventParams) {
    emit('edit-activated', e);
  }
  /** 只对 edit-config 配置时有效，当单元格激活时如果是禁用状态时会触发该事件 */
  async function editDisabledEvent(e: VxeGridDefines.EditDisabledEventParams) {
    emit('edit-disabled', e);
  }
  /** 只对 type=radio 有效，当手动勾选并且值发生改变时触发的事件 */
  async function radioChangeEvent(e: VxeGridDefines.RadioChangeEventParams) {
    emit('radio-change', e);
  }
  /** 只对 type=checkbox 有效，当手动勾选并且值发生改变时触发的事件 */
  async function checkboxChangeEvent(e: VxeGridDefines.CheckboxChangeEventParams) {
    emit('checkbox-change', e);
  }

  /** 表格滚动时会触发该事件 */
  async function scrollEvent(e: VxeGridDefines.ScrollEventParams) {
    // console.log('scroll', e);
    if (e.isX) {
      expandContentLeft.value = e.scrollLeft;
    }
    emit('scroll', e);
  }

  const getVxeTable = computed(() => getTable.value?.$el?.querySelector('.vxe-table'));
  /** 展开行内容宽度 */
  const expandContentWidth = ref('unset');
  /** 展开行内容左间距 */
  const expandContentLeft = ref(0);

  let resizeObserver: ResizeObserver;
  onMounted(() => {
    resizeObserver = new ResizeObserver(() => {
      const vxeTb = getVxeTable.value;
      // console.log({
      //   11: getTable.value?.$el?.clientWidth,
      //   22: getTable.value?.$el?.offsetWidth,
      //   33: vxeTb?.clientWidth,
      // });
      expandContentWidth.value = vxeTb?.clientWidth ? `${vxeTb.clientWidth}px` : 'unset';
    });
    resizeObserver?.observe(getVxeTable.value); // 绑定元素
  });
  onUnmounted(() => {
    resizeObserver?.disconnect(); // 取消绑定
  });
</script>

<style lang="less">
  .vxe-tools--wrapper {
    // padding: 10px 16px;
    // border-top: 1px solid @border-color-base;
    // background-color: var(--vxe-modal-header-background-color);

    button + button {
      margin-left: 10px;
    }

    div + div {
      margin-left: 10px;
    }

    button + div {
      margin-left: 10px;
    }

    div + button {
      margin-left: 10px;
    }
  }

  // .vxe-table--render-default .vxe-body--expanded-column {
  //   // border-bottom: unset;
  //   // background-color: transparent;
  // }

  .vxe-table--render-default .vxe-body--expanded-column.col--ellipsis > .vxe-body--expanded-cell {
    // background-color: transparent;
    // overflow: unset;
    z-index: 10;
  }
</style>
